package com.sangmo.fts.process.factoring.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.data.filter.NativeQueryBuilder;
import com.sangmo.boot.framework.data.filter.PageResult;
import com.sangmo.boot.framework.data.filter.PageSearch;
import com.sangmo.boot.framework.data.filter.ValueFilter;
import com.sangmo.boot.framework.plugin.dataview.crud.service.DelegateViewService;
import com.sangmo.boot.framework.plugin.dataview.crud.service.ViewService;
import com.sangmo.boot.framework.plugin.dataview.spi.jpa.NativeQueryBuilderFactory;
import com.sangmo.fts.common.authority.AuthorityFilterChain;
import com.sangmo.fts.common.authority.Rights;
import com.sangmo.fts.common.authority.sql.WhereModifier;
import com.sangmo.fts.process.factoring.model.FfFactoringContract;
import com.sangmo.fts.process.receivable.model.RpfContract;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class FfFactoringContractService extends DelegateViewService<FfFactoringContract> {

    @Autowired
    private FfFactoringContractEntityService ffFactoringContractEntityService;

    @Override
    protected ViewService<FfFactoringContract> getEntityService() {
        return ffFactoringContractEntityService;
    }

    public void bankConfirm(Long id) {
        FfFactoringContract contract = this.get(id);
        if (null == contract.getBankConfirmDoc()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffFactoringContract.bankConfirm.permit.disabled");
        }
        if (contract.isBankConfirm()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffFactoringContract.bankConfirm.state.wrong");
        }
        ffFactoringContractEntityService.bankConfirm(contract);
    }

    public void sellerConfirm(Long id) {
        FfFactoringContract contract = this.get(id);
        if (null == contract.getSellerConfirmDoc()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffFactoringContract.sellerConfirm.permit.disabled");
        }
        if (contract.isSellerConfirm()) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffFactoringContract.sellerConfirm.state.wrong");
        }
        ffFactoringContractEntityService.sellerConfirm(contract);
    }

    public PageResult<FfFactoringContract> selection(PageSearch ps) {
        WhereModifier modifier = AuthorityFilterChain.getInstance().createNativeModifier("a", FfFactoringContract.class, Rights.READ);
        ps.getFilters().add(new ValueFilter("bankConfirm", ValueFilter.OP_EQ, true));
        ps.getFilters().add(new ValueFilter("sellerConfirm", ValueFilter.OP_EQ, true));
        NativeQueryBuilder builder = NativeQueryBuilderFactory.create()
                .putAlias("a", FfFactoringContract.class)
                .selectForm("SELECT a.* FROM ff_factoring_contract a ")
                .where("NOT EXISTS (select 1 from ff_transfer_apply ta where ta.contract_id = a.id and ta.deleted = 0) ")
                .where(ps)
                .where(modifier.getSql()).putVariables(modifier.getVariables())
                .transform(FfFactoringContract.class);
        return builder.buildPage();
    }

    public FfFactoringContract findAvailable(Long id, Long trainingId) {
        return ffFactoringContractEntityService.findAvailableById(id, trainingId);
    }

}
